package scenic.study.thread.synchronizedandlock;

import org.apache.log4j.Logger;
import org.junit.Test;
import scenic.MyLogger;

/**
 * Created by scenic on 2017/1/17.
 * 测试 synchronized  and lock 的性能
 */
public class SynchronizedAndLockPerformance {
    private static Logger logger = MyLogger.get(SynchronizedAndLockPerformance.class);

    //用data代表在线编辑功能的编辑框
    //实现的需求： 只允许同时一个人进行写的操作， 可以多个人进行读取的操作
    public static class Data {
        //用buffer模拟一个在线编辑的功能内容
        private final char[] buffer;

        public Data(int size) {
            this.buffer = new char[size];
            for (int i = 0; i < size; i++) {
                buffer[i] = '*';
            }
        }

        public synchronized String read() throws InterruptedException {
            StringBuffer result = new StringBuffer();
            for (char c : buffer) {
                result.append(c);
            }
            Thread.sleep(100);
            return result.toString();
        }

        public synchronized void write(char c) throws InterruptedException {
            for (int i = 0; i < buffer.length; i++) {
                buffer[i] = c;
                Thread.sleep(100);
            }
        }

    }

    public static class ReaderThread extends Thread {
        private final Data data;

        public ReaderThread(Data data) {
            this.data = data;
        }

        @Override
        public void run() {

            try {
                while (true) {
                    String result = data.read();
                    logger.debug(Thread.currentThread().getName() + "=>" + result);
                }


            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
    }

    public static class WriteThread extends Thread {
        private final Data data;
        private final String str;
        private int index = 0;

        public WriteThread(Data data, String str) {
            this.data = data;
            this.str = str;
        }

        @Override
        public void run() {

            try {
                //用一个循环代表一个用户一直在进行编辑操作
                while (true) {
                    char c = next();
                    data.write(c);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        private char next() {
            char c = str.charAt(index);
            index++;
            if(index >= str.length()){
                index = 0;
            }
            return c ;
        }

    }

    public static void main(String args[]) {
        Data data = new Data(10);
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
//
        new WriteThread(data,"ABC").start();
//        new WriteThread(data,"123").start();

    }

    public static class Client {
        @Test
        public void testClient () throws InterruptedException {
            Data data = new Data(10);
            new ReaderThread(data).start();
            new ReaderThread(data).start();
            new ReaderThread(data).start();

            new WriteThread(data,"ABC").start();
            new WriteThread(data,"123").start();

            synchronized (this) {
                this.wait();
            }

        }


    }

}
